using B.S.Medical.Api.Write.Application.Command.Pay;
using B.S.Medical.Domain.Medical;
using B.S.Medical.Domain.Payment;
using B.S.Medical.ErrorCode;
using B.S.Medical.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.Medical.Api.Write.Application.Handler.Pay
{
    /// <summary>
    /// 退款处理器
    /// </summary>
    public class RefundPaymentHandler : IRequestHandler<RefundPaymentCommand, ApiResult<bool>>
    {
        private readonly IBaseRepository<PaymentRecordModel> _paymentRepository;
        private readonly IBaseRepository<PatientBalance> _patientBalanceRepository;
        private readonly ILogger<RefundPaymentHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        public RefundPaymentHandler(
            IBaseRepository<PaymentRecordModel> paymentRepository,
            IBaseRepository<PatientBalance> patientBalanceRepository,
            ILogger<RefundPaymentHandler> logger)
        {
            _paymentRepository = paymentRepository;
            _patientBalanceRepository = patientBalanceRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理退款命令
        /// </summary>
        public async Task<ApiResult<bool>> Handle(RefundPaymentCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation($"开始处理退款: OrderNo={request.OrderNo}, RefundAmount={request.RefundAmount}");

                // 查询支付记录
                var payment = _paymentRepository.GetAll()
                    .Where(p => p.OrderNo == request.OrderNo && !p.IsDeleted)
                    .FirstOrDefault();

                if (payment == null)
                {
                    _logger.LogWarning($"未找到支付记录: {request.OrderNo}");
                    return new ApiResult<bool>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "未找到支付记录",
                        Data = false
                    };
                }

                // 检查支付状态
                if (!payment.IsPaid || payment.PayStatus != "已支付" && payment.PayStatus != "TRADE_SUCCESS")
                {
                    _logger.LogWarning($"支付记录状态不允许退款: {payment.PayStatus}");
                    return new ApiResult<bool>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "只有已支付的订单才能退款",
                        Data = false
                    };
                }

                // 确定退款金额
                var refundAmount = request.RefundAmount ?? payment.PayAmount;
                
                // 验证退款金额
                if (refundAmount <= 0 || refundAmount > payment.PayAmount)
                {
                    _logger.LogWarning($"退款金额无效: {refundAmount}, 原支付金额: {payment.PayAmount}");
                    return new ApiResult<bool>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "退款金额无效",
                        Data = false
                    };
                }

                // 更新支付记录
                payment.PayStatus = "已退款";
                payment.IsPaid = false;
                payment.RefundAmount = refundAmount;
                payment.RefundStatus = "退款成功";
                payment.RefundTime = DateTime.Now;
                if (!string.IsNullOrEmpty(request.RefundTradeNo))
                {
                    payment.RefundTradeNo = request.RefundTradeNo;
                }
                payment.UpdateTime = DateTime.Now;

                // 更新患者余额
                var patientBalance = _patientBalanceRepository.GetAll()
                    .Where(b => b.PatientId == payment.PatientId && !b.IsDeleted)
                    .FirstOrDefault();

                if (patientBalance != null)
                {
                    // 只有普通支付的退款才增加余额，充值的退款不处理余额
                    if (payment.ItemName != "余额充值")
                    {
                        patientBalance.Balance += refundAmount;
                        patientBalance.UpdateTime = DateTime.Now;
                        patientBalance.LastUpdatedTime = DateTime.Now;
                        patientBalance.Remark = $"退款 {refundAmount} 元" + 
                            (!string.IsNullOrEmpty(request.RefundReason) ? $"，原因：{request.RefundReason}" : "");
                        
                        await _patientBalanceRepository.UpdateAsync(patientBalance);
                        _logger.LogInformation($"退款到余额: 患者ID={payment.PatientId}, 金额={refundAmount}, 当前余额={patientBalance.Balance}");
                    }
                    else
                    {
                        _logger.LogInformation($"余额充值退款不处理余额: 患者ID={payment.PatientId}, 金额={refundAmount}");
                    }
                }
                else
                {
                    _logger.LogWarning($"未找到患者余额记录: PatientId={payment.PatientId}");
                }

                // 保存支付记录
                await _paymentRepository.UpdateAsync(payment);

                _logger.LogInformation($"退款处理成功: OrderNo={request.OrderNo}, RefundAmount={refundAmount}");

                return new ApiResult<bool>
                {
                    Code = ApiEnum.Success,
                    Msg = "退款处理成功",
                    Data = true
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"退款处理失败: OrderNo={request.OrderNo}, Error={ex.Message}");
                return new ApiResult<bool>
                {
                    Code = ApiEnum.Error,
                    Msg = $"退款处理失败: {ex.Message}",
                    Data = false
                };
            }
        }
    }
} 